#include "threads/malloc.h"
#include "vm/page.h"

bool page_init (struct hash* arg_h)
{
    return hash_init (arg_h, page_init_semi, page_less_func, NULL);
}

void page_delete (struct hash* arg_h)
{
    hash_destroy (arg_h, page_release);
}

void page_release (struct hash_elem* arg_e)
{
    struct page_info* temp_page = hash_entry (arg_e, struct page_info, elem);
    free(temp_page);
}

struct page_info* get_new_page (struct hash* arg_h, void* upage)
{
    struct page_info* ret = (struct page_info*) malloc (sizeof (struct page_info));

    if (ret == NULL)
    {
       return NULL;
    }
    else
    {
       ret->upage = upage;

       hash_insert (arg_h, &ret->elem);
       return ret;
    }
}

struct page_info* get_page (struct hash* arg_h, void* arg_upage)
{
    struct page_info temp_page;
    temp_page.upage = arg_upage;

    struct hash_elem* temp_el = hash_find (arg_h, &temp_page.elem);

    if (temp_el == NULL)
    {
       return NULL;
    }
    else
    {
       return hash_entry (temp_el, struct page_info, elem);
    }
}

unsigned page_init_semi (struct hash_elem* arg_e)
{
    struct page_info* temp_page = hash_entry (arg_e, struct page_info, elem);
    return hash_int ((int)temp_page->upage);
}

bool page_less_func (struct hash_elem* left, struct hash_elem* right)
{
    struct page_info* page_l = hash_entry (left, struct page_info, elem);
    struct page_info* page_r = hash_entry (right, struct page_info, elem);

    return page_l->upage < page_r->upage;
}

